package _04_queue.my_implements;

import org.junit.Test;

import java.lang.invoke.TypeDescriptor;

import static java.lang.System.out;

/**
 * @author: mornd
 * @dateTime: 2023/6/4 - 21:42
 */
public class MyTest {
    @Test
    public void test() {
        LinkedListQueue<Integer> queue = new LinkedListQueue<>(2);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
//        System.out.println(queue.poll());
//        System.out.println(queue.poll());
//        System.out.println(queue.peek());
//        System.out.println(queue.poll());
        out.println(queue);
    }

    @Test
    public void test1() {
        ArrayQueue1<Integer> queue = new ArrayQueue1<>(2);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        out.println(queue);
        queue.clear();
//        System.out.println(queue.poll());
//        System.out.println(queue.poll());
//        System.out.println(queue.peek());
//        System.out.println(queue.poll());
        out.println(queue);
    }

    @Test
    public void test2() {
        ArrayQueue2<Integer> queue = new ArrayQueue2<>(2);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        out.println(queue);
        queue.clear();
        out.println(queue);
    }

    @Test
    public void test3() {
        ArrayQueue<Integer> queue = new ArrayQueue<>(2);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        out.println(queue);
        out.println(queue.poll());
        out.println(queue.poll());
        out.println(queue.poll());
    }

    @Test
    public void test4() {
        int a = 2147483647;
        out.println(++a);
        out.println(++a);
        // 转为 long 类型存储，数据正常显示
        long b = Integer.toUnsignedLong(a);
        out.println(b);
    }

    @Test
    public void test5() {
        int a = 2147483647;
        int b = (int) (Integer.toUnsignedLong(a + 1) % 10);
        out.println(b);
    }

    @Test
    public void test6() {
        int a = 3454;
        // 如果 b 是2的n次方，那么下面的 c==d 成立
        int b = 8;

        int c = a % b;
        int d = a & (b - 1);
        out.println("c=" + c + ", d=" + d + ", " + (c == d));
    }

    @Test
    public void test7() {
        // n & 1 == 0 则n是偶数，否则n是奇数
        out.println((10 & 1) == 0);
        out.println((11 & 1) == 0);
    }

    /**
     * 位运算符 & | ^
     */
    @Test
    public void test8() {
        out.println(123 & 32); // 32
        out.println(234 & 4); // 0
        out.println(386 & 543); // 2
        out.println(57 & 97); // 33
        out.println(23123 & 352342); // 16466
        out.println(43245632 & 5); // 0
        out.println();

        out.println(458 | 5); // 463
        out.println(789 | 43); // 831
        out.println(126 | 453); // 511
        out.println(65 | 24); // 89
        out.println(574953 | 68759323); // 68808699
        out.println();

        out.println(23 ^ 567); // 544
        out.println(356 ^ 654); // 1002
        out.println(23 ^ 378); // 365
        out.println(53 ^ 74); // 127
        out.println(234213535 ^ 32576354); // 201638909

    }

    /**
     * 位运算符：非  ~ 测试
     */
    @Test
    public void test8_1() {
        /*
            运算时先不管~符号，先得出其对应的2进制数
            步骤为：转为2进制=>取反=>转为10进制
            -1转为2进制 => 11111111111111111111111111111111 取反（0的10进制还是0）=> 0
         */
        out.println(~-1); // 0

        /*
            0的2进制还是0 取反=> 11111111111111111111111111111111 =>  转为10进制 -1
         */
        out.println(~0); // -1

        /*
            13转为2进制 => 1101 取反=> 11111111111111111111111111110010 转为10进制=> -14
         */
        out.println(~13); // -14

        /*
            5的2进制 101 取反=> 11111111111111111111111111111010 转为10进制 -6
         */
        out.println(~5); // -6

        /*
            2进制为 010011010010 取反=> 11111111111111111111101100101101 转为10进制 => -1235
         */
        out.println(~1234); // -1235

        /*
            2进制为 00100010001101000011011011000100 取反=> 11011101110010111100100100111011 转为10进制 => -573847237
         */
        out.println(~573847236); // -573847237
    }

    @Test
    public void test8_2() {
        out.println(Integer.toBinaryString(2)); // 10
        out.println(Integer.toBinaryString(1)); // 1
        out.println(Integer.toBinaryString(0)); // 0
        out.println(Integer.toBinaryString(-1)); // 11111111111111111111111111111111
        out.println(Integer.toBinaryString(-2)); // 11111111111111111111111111111110
    }

    /**
     * 对数测试 方式1
     * 给定一个数c，求离c最进，比c大的2^n数
     */
    @Test
    public void testLogarithm() {
        int c = 31;
        /*
            已知：
            2的4次方 = 16
            2的5次方 = 32
            2的6次方 = 64

            求出以2为底 30的对数 + 1
            log2(30) + 1

            java没有直接求以2为底的对数，需转换为
            log2(x) = log10(x) / log10(2)
         */

        //Math.log(); // 以自然数为底的对数
        //Math.log10(); // 以10为底的对数

//        double v = Math.log10(c) / Math.log10(2) + 1; // // 5.906890595608519
        int v = (int) (Math.log10(c) / Math.log10(2)) + 1; // 5
        /*
            上面求出v的值为5，如何快速得到2^5
            1<<1 = 2
            1<<2 = 4
            1<<3 = 8
            1<<4 = 16
            1<<5 = 32
            得到的公式：1 << 5
         */
        out.println(1 << 5);
        out.println(Math.pow(2, 5)); // 得到2的5次方

        /*
            如果c本身就是2的n次方，需将c-1
         */
        int v2 = 1 << (int) (Math.log10(c - 1) / Math.log10(2)) + 1;
        out.println(v2);
    }

    /**
     * 对数测试 方式2
     */
    @Test
    public void testLogarithm2() {
        int c = 30;

        c -= 1;
        c |= c >> 1;
        c |= c >> 2;
        c |= c >> 4;
        c |= c >> 8;
        c |= c >> 16;
        c += 1;

        out.println(c);
    }

}
